using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BanZuiCloudControlAgent.Core.Tasks.Enums;
using BanZuiCloudControlAgent.Core.Tasks.Models;
using BanZuiCloudControlAgent.Utils.Logging;

namespace BanZuiCloudControlAgent.Core.Tasks.Base
{
    /// <summary>
    /// 任务基类，所有具体任务都应继承此类
    /// </summary>
    public abstract class BaseTask : ITask
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        protected readonly Logger _logger;
        
        /// <summary>
        /// 任务ID
        /// </summary>
        public string TaskId { get; set; }
        
        /// <summary>
        /// 任务类型
        /// </summary>
        public TaskType TaskType { get; set; }
        
        /// <summary>
        /// 任务状态
        /// </summary>
        public TaskState Status { get; set; }
        
        /// <summary>
        /// 任务优先级
        /// </summary>
        public TaskPriority Priority { get; set; }
        
        /// <summary>
        /// 任务参数
        /// </summary>
        public Dictionary<string, object> Parameters { get; set; }
        
        /// <summary>
        /// 任务进度（0-100）
        /// </summary>
        public int Progress { get; protected set; }
        
        /// <summary>
        /// 任务结果
        /// </summary>
        public TaskResult Result { get; protected set; }
        
        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage => Result?.ErrorMessage;
        
        /// <summary>
        /// 任务创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }
        
        /// <summary>
        /// 任务开始时间
        /// </summary>
        public DateTime? StartTime { get; protected set; }
        
        /// <summary>
        /// 任务完成时间
        /// </summary>
        public DateTime? CompleteTime { get; protected set; }
        
        /// <summary>
        /// 暂停状态检查事件
        /// </summary>
        private readonly AutoResetEvent _pauseEvent = new AutoResetEvent(true);
        
        /// <summary>
        /// 构造函数
        /// </summary>
        protected BaseTask()
        {
            _logger = LogManager.GetLogger(this.GetType().Name);
            TaskId = Guid.NewGuid().ToString();
            Status = TaskState.Pending;
            Priority = TaskPriority.Normal;
            Parameters = new Dictionary<string, object>();
            Progress = 0;
            CreateTime = DateTime.Now;
        }
        
        /// <summary>
        /// 执行任务
        /// </summary>
        /// <param name="context">任务上下文</param>
        /// <returns>任务结果</returns>
        public abstract Task<TaskResult> ExecuteAsync(TaskContext context);
        
        /// <summary>
        /// 暂停任务
        /// </summary>
        public virtual Task PauseAsync()
        {
            if (Status == TaskState.Running)
            {
                Status = TaskState.Paused;
                _pauseEvent.Reset(); // 重置事件，使等待的线程暂停
                _logger.Info($"任务已暂停: {TaskId}, 类型: {TaskType}");
            }
            
            return Task.CompletedTask;
        }
        
        /// <summary>
        /// 恢复任务
        /// </summary>
        public virtual Task ResumeAsync()
        {
            if (Status == TaskState.Paused)
            {
                Status = TaskState.Running;
                _pauseEvent.Set(); // 设置事件，使等待的线程继续
                _logger.Info($"任务已恢复: {TaskId}, 类型: {TaskType}");
            }
            
            return Task.CompletedTask;
        }
        
        /// <summary>
        /// 取消任务
        /// </summary>
        public virtual Task CancelAsync()
        {
            if (Status == TaskState.Running || Status == TaskState.Paused || Status == TaskState.Pending)
            {
                Status = TaskState.Canceled;
                Result = TaskResult.Canceled();
                CompleteTime = DateTime.Now;
                _pauseEvent.Set(); // 设置事件，使等待的线程继续并检查取消状态
                _logger.Info($"任务已取消: {TaskId}, 类型: {TaskType}");
            }
            
            return Task.CompletedTask;
        }
        
        /// <summary>
        /// 检查任务是否应该继续执行
        /// </summary>
        /// <returns>如果任务应该继续执行，则返回true；否则返回false</returns>
        protected bool ShouldContinue()
        {
            // 如果任务已取消，则不应继续执行
            if (Status == TaskState.Canceled)
            {
                _logger.Debug($"任务已取消，停止执行: {TaskId}");
                return false;
            }
            
            return true;
        }
        
        /// <summary>
        /// 检查暂停和取消状态，如果任务被暂停则等待恢复，如果任务被取消则返回false
        /// </summary>
        /// <param name="cancellationToken">可选的取消令牌</param>
        /// <returns>如果任务应该继续执行，则返回true；如果任务被取消，则返回false</returns>
        protected async Task<bool> CheckPauseAndCancellationAsync(CancellationToken cancellationToken = default)
        {
            // 如果任务已取消，则不应继续执行
            if (Status == TaskState.Canceled || cancellationToken.IsCancellationRequested)
            {
                _logger.Debug($"任务已取消，停止执行: {TaskId}");
                return false;
            }
            
            // 如果任务已暂停，则等待恢复
            if (Status == TaskState.Paused)
            {
                _logger.Debug($"任务已暂停，等待恢复: {TaskId}");
                
                // 使用Task.Run将同步等待转换为异步等待
                await Task.Run(() => 
                {
                    while (Status == TaskState.Paused && !cancellationToken.IsCancellationRequested)
                    {
                        // 等待恢复信号，最多等待1秒，然后重新检查状态
                        _pauseEvent.WaitOne(TimeSpan.FromSeconds(1));
                    }
                }, cancellationToken);
                
                // 再次检查取消状态
                if (Status == TaskState.Canceled || cancellationToken.IsCancellationRequested)
                {
                    _logger.Debug($"等待恢复过程中任务被取消: {TaskId}");
                    return false;
                }
            }
            
            return true;
        }
        
        /// <summary>
        /// 延迟指定的时间，同时检查暂停和取消状态
        /// </summary>
        /// <param name="milliseconds">延迟的毫秒数</param>
        /// <param name="cancellationToken">可选的取消令牌</param>
        /// <returns>如果任务应该继续执行，则返回true；如果任务被取消，则返回false</returns>
        protected async Task<bool> DelayWithPauseCheckAsync(int milliseconds, CancellationToken cancellationToken = default)
        {
            // 将延迟分成多个小段，每段之后检查暂停和取消状态
            int segmentSize = 1000; // 1秒
            int remainingDelay = milliseconds;
            
            while (remainingDelay > 0)
            {
                int currentDelay = Math.Min(segmentSize, remainingDelay);
                
                // 检查暂停和取消状态
                if (!await CheckPauseAndCancellationAsync(cancellationToken))
                {
                    return false;
                }
                
                // 延迟指定的时间
                await Task.Delay(currentDelay, cancellationToken);
                remainingDelay -= currentDelay;
            }
            
            return true;
        }
        
        /// <summary>
        /// 更新任务进度
        /// </summary>
        /// <param name="progress">进度值（0-100）</param>
        protected void UpdateProgress(int progress)
        {
            Progress = Math.Max(0, Math.Min(100, progress));
            _logger.Debug($"任务进度更新: {TaskId}, 类型: {TaskType}, 进度: {Progress}%");
            OnProgressChanged(Progress);
        }
        
        /// <summary>
        /// 设置任务开始
        /// </summary>
        protected void SetTaskStarted()
        {
            Status = TaskState.Running;
            StartTime = DateTime.Now;
            _logger.Info($"任务开始执行: {TaskId}, 类型: {TaskType}");
        }
        
        /// <summary>
        /// 设置任务完成
        /// </summary>
        /// <param name="result">任务结果</param>
        protected void SetTaskCompleted(TaskResult result)
        {
            Result = result;
            Status = result.Status;
            CompleteTime = DateTime.Now;
            
            if (result.IsSuccess)
            {
                _logger.Info($"任务执行成功: {TaskId}, 类型: {TaskType}, 消息: {result.Message}");
            }
            else
            {
                _logger.Warn($"任务执行失败: {TaskId}, 类型: {TaskType}, 错误: {result.ErrorMessage}");
                if (result.Exception != null)
                {
                    _logger.Error($"任务异常: {TaskId}", result.Exception);
                }
            }
        }
        
        /// <summary>
        /// 进度变化事件
        /// </summary>
        public event EventHandler<int> ProgressChanged;
        
        /// <summary>
        /// 触发进度变化事件
        /// </summary>
        /// <param name="progress">进度值</param>
        protected virtual void OnProgressChanged(int progress)
        {
            ProgressChanged?.Invoke(this, progress);
        }
        
        /// <summary>
        /// 获取参数值
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="key">参数键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>参数值</returns>
        protected T GetParameter<T>(string key, T defaultValue = default)
        {
            if (Parameters != null && Parameters.TryGetValue(key, out object value))
            {
                if (value is T typedValue)
                {
                    return typedValue;
                }
                
                try
                {
                    // 尝试转换
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                catch
                {
                    _logger.Warn($"无法将参数 {key} 转换为类型 {typeof(T).Name}");
                    return defaultValue;
                }
            }
            
            return defaultValue;
        }
    }
} 